<template>
  <div class="medicine-container">
    <!-- 顶部操作区 -->
    <div class="operation-area flex-between">
      <div class="left">
        <el-button type="primary" @click="handleAdd">
          <el-icon>
            <Plus />
          </el-icon>新增药品
        </el-button>
        <el-button type="success" @click="handleImport">
          <el-icon>
            <Upload />
          </el-icon>导入
        </el-button>
        <el-button type="warning" @click="handleExport">
          <el-icon>
            <Download />
          </el-icon>导出
        </el-button>
      </div>
      <div class="right">
        <el-input v-model="searchForm.medicineName" placeholder="搜索药品名称" clearable @keyup.enter="handleSearch">
          <template #prefix>
            <el-icon>
              <Search />
            </el-icon>
          </template>
        </el-input>
      </div>
    </div>

    <!-- 搜索区域 -->
    <el-card class="search-area">
      <el-form :inline="true" :model="searchForm" @keyup.enter="handleSearch" class="search-form">
        <el-form-item label="药品名称">
          <el-input v-model="searchForm.medicineName" placeholder="请输入药品名称" clearable />
        </el-form-item>
        <el-form-item label="生产厂家">
          <el-input v-model="searchForm.manufacturer" placeholder="请输入生产厂家" clearable />
        </el-form-item>
        <el-form-item label="通用分类">
          <el-select v-model="searchForm.commonCategoryId" placeholder="请选择通用分类" clearable filterable
            class="category-select">
            <el-option v-for="item in commonCategoryOptions" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>
        <el-form-item label="处方类型">
          <el-select v-model="searchForm.prescriptionCategoryId" placeholder="请选择处方类型" clearable filterable
            class="category-select">
            <el-option v-for="item in prescriptionCategoryOptions" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>
        <div class="search-buttons">
          <el-button type="primary" @click="handleSearch">
            <el-icon>
              <Search />
            </el-icon>搜索
          </el-button>
          <el-button @click="resetSearch">
            <el-icon>
              <Refresh />
            </el-icon>重置
          </el-button>
        </div>
      </el-form>
    </el-card>

    <!-- 表格区域 -->
    <el-card class="table-area" v-loading="loading">
      <el-table :data="tableData" border style="width: 100%" :header-cell-style="{ background: '#f5f7fa' }"
        highlight-current-row>
        <el-table-column type="selection" width="55" align="center" />
        <el-table-column prop="medicineId" label="ID" width="80" align="center" />
        <el-table-column label="药品信息" min-width="200">
          <template #default="{ row }">
            <div class="medicine-info">
              <el-image v-if="row.imageUrl" :src="row.imageUrl" :preview-src-list="[row.imageUrl]" fit="cover"
                class="medicine-image" loading="lazy" />
              <el-icon v-else class="no-image">
                <Picture />
              </el-icon>
              <div class="medicine-text">
                <div class="medicine-name">{{ row.medicineName }}</div>
                <div class="medicine-spec">{{ row.specification }}</div>
              </div>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="dosageForm" label="剂型" width="100" align="center" />
        <el-table-column prop="manufacturer" label="生产厂家" min-width="150" show-overflow-tooltip />
        <el-table-column prop="price" label="单价" width="100" align="center">
          <template #default="{ row }">
            <span class="price">¥{{ row.price }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="salesVolume" label="库存" width="100" align="center" sortable />
        <el-table-column label="分类信息" width="200" align="center">
          <template #default="{ row }">
            <div class="category-info">
              <el-tag size="small" type="success" :effect="row.commonCategoryName ? 'light' : 'plain'">
                {{ row.commonCategoryName || '未分类' }}
              </el-tag>
              <el-tag size="small" type="warning" :effect="row.prescriptionCategoryName ? 'light' : 'plain'">
                {{ row.prescriptionCategoryName || '未分类' }}
              </el-tag>
            </div>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="180" fixed="right" align="center">
          <template #default="{ row }">
            <el-button link type="primary" @click="handleDetail(row)">
              <el-icon>
                <View />
              </el-icon>详情
            </el-button>
            <el-button link type="primary" @click="handleEdit(row)">
              <el-icon>
                <Edit />
              </el-icon>编辑
            </el-button>
            <el-popconfirm title="确定要删除该药品吗？" @confirm="handleDelete(row)" confirm-button-text="确定"
              cancel-button-text="取消">
              <template #reference>
                <el-button link type="danger">
                  <el-icon>
                    <Delete />
                  </el-icon>删除
                </el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页 -->
      <div class="pagination-container">
        <el-pagination v-model:current-page="queryParams.pageNum" v-model:page-size="queryParams.pageSize"
          :page-sizes="[10, 20, 50, 100]" :total="total" layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange" @current-change="handleCurrentChange" />
      </div>
    </el-card>

    <!-- 新增/编辑对话框 -->
    <el-dialog v-model="dialogVisible" :title="dialogType === 'add' ? '新增药品' : '编辑药品'" width="60%" destroy-on-close>
      <medicine-form ref="formRef" :form-data="formData" :type="dialogType" />
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" :loading="submitLoading" @click="submitForm">
            确认
          </el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 详情抽屉 -->
    <el-drawer v-model="drawerVisible" title="药品详情" size="50%" destroy-on-close>
      <medicine-detail :detail-data="detailData" />
    </el-drawer>

    <!-- 导入对话框 -->
    <el-dialog v-model="importDialogVisible" title="导入药品信息" width="500px" destroy-on-close
      :close-on-click-modal="false">
      <el-upload ref="uploadRef" class="upload-demo" drag action="#" :auto-upload="false" :on-change="handleFileChange"
        :on-remove="handleFileRemove" :before-upload="beforeUpload" :limit="1" accept=".xlsx,.xls">
        <el-icon class="el-icon--upload">
          <UploadFilled />
        </el-icon>
        <div class="el-upload__text">
          将文件拖到此处，或<em>点击上传</em>
        </div>
        <template #tip>
          <div class="el-upload__tip">
            <div class="tip-content">
              <span>只能上传 xlsx/xls 文件，且文件大小不超过 10MB</span>
              <el-button type="primary" link @click="downloadTemplate">
                <el-icon>
                  <Download />
                </el-icon>下载模板
              </el-button>
            </div>
            <div class="tip-rules">
              <p>导入说明：</p>
              <ol>
                <li>请严格按照模板格式填写数据</li>
                <li>标记 * 的字段为必填项</li>
                <li>批准文号必须唯一</li>
                <li>价格必须大于0</li>
                <li>库存数量必须大于等于0</li>
              </ol>
            </div>
          </div>
        </template>
      </el-upload>

      <!-- 导入结果展示 -->
      <div v-if="importResult.show" class="import-result">
        <div class="result-title">导入结果：</div>
        <div class="result-content">
          <p>成功数量：<span class="success">{{ importResult.successCount }}</span></p>
          <p>失败数量：<span class="error">{{ importResult.failCount }}</span></p>
          <div v-if="importResult.errorMessages?.length" class="error-messages">
            <p>错误详情：</p>
            <el-scrollbar height="150px">
              <p v-for="(error, index) in importResult.errorMessages" :key="index" class="error-item">
                {{ error }}
              </p>
            </el-scrollbar>
          </div>
        </div>
      </div>

      <template #footer>
        <span class="dialog-footer">
          <el-button @click="closeImportDialog">关闭</el-button>
          <el-button type="primary" :loading="importLoading" @click="submitImport">
            确认导入
          </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox, ElLoading } from 'element-plus'
import {
  Plus,
  Search,
  Refresh,
  Upload,
  Download,
  View,
  Edit,
  Delete,
  UploadFilled,
  Picture
} from '@element-plus/icons-vue'
import {
  getMedicineList,
  getMedicineDetail,
  addMedicine,
  updateMedicine,
  deleteMedicine,
  exportMedicine,
  importMedicine,
  downloadMedicineTemplate,
  getCommonCategories,
  getPrescriptionCategories
} from '../../api/medicine'
import MedicineForm from './components/MedicineForm.vue'
import MedicineDetail from './components/MedicineDetail.vue'

// 数据定义
const loading = ref(false)
const submitLoading = ref(false)
const dialogVisible = ref(false)
const dialogType = ref('add')
const formRef = ref(null)

// 查询参数
const queryParams = reactive({
  pageNum: 1,
  pageSize: 10,
})

// 总数据量
const total = ref(0)

// 获取分类数据并缓存
const commonCategoryOptions = ref([])
const prescriptionCategoryOptions = ref([])

const fetchCategories = async () => {
  try {
    const [commonRes, prescriptionRes] = await Promise.all([
      getCommonCategories(),
      getPrescriptionCategories()
    ])

    if (commonRes.code === 200) {
      commonCategoryOptions.value = commonRes.data
    }

    if (prescriptionRes.code === 200) {
      prescriptionCategoryOptions.value = prescriptionRes.data
    }
  } catch (error) {
    console.error('获取分类数据失败:', error)
    ElMessage.error('获取分类数据失败')
  }
}

// 搜索表单
const searchForm = reactive({
  medicineName: '',
  manufacturer: '',
  commonCategoryId: '',
  prescriptionCategoryId: ''
})

// 表格数据
const tableData = ref([])
const formData = ref({})

// 抽屉相关
const drawerVisible = ref(false)
const detailData = ref({})

// 导入相关状态
const uploadRef = ref(null)
const importDialogVisible = ref(false)
const importLoading = ref(false)
const importFile = ref(null)
const importResult = reactive({
  show: false,
  successCount: 0,
  failCount: 0,
  errorMessages: []
})

// 获取列表数据
const fetchList = async () => {
  try {
    loading.value = true
    const params = {
      pageNum: queryParams.pageNum,
      pageSize: queryParams.pageSize,
      ...searchForm
    }
    const res = await getMedicineList(params)
    console.log('API 返回:', res)
    if (res.code === 200) {
      tableData.value = res.data.list || []
      total.value = res.data.total || 0
    } else {
      ElMessage.error(res.message || '获取数据失败')
    }
  } catch (error) {
    console.error('获取列表失败:', error)
    ElMessage.error('系统错误')
  } finally {
    loading.value = false
  }
}

// 搜索
const handleSearch = () => {
  queryParams.pageNum = 1
  fetchList()
}

// 重置搜索
const resetSearch = () => {
  Object.keys(searchForm).forEach(key => {
    searchForm[key] = ''
  })
  handleSearch()
}

// 新增药品
const handleAdd = () => {
  dialogType.value = 'add'
  formData.value = {}
  dialogVisible.value = true
}

// 编辑药品
const handleEdit = async (row) => {
  try {
    // 获取详细信息
    const res = await getMedicineDetail(row.medicineId)
    if (res.code === 200) {
      dialogType.value = 'edit'
      formData.value = res.data
      dialogVisible.value = true
    } else {
      ElMessage.error(res.message || '获取药品详情失败')
    }
  } catch (error) {
    console.error('获取药品详情失败:', error)
    ElMessage.error('系统错误')
  }
}

// 提交表单
const submitForm = async () => {
  if (!formRef.value) {
    ElMessage.error('表单实例不存在')
    return
  }

  try {
    submitLoading.value = true
    const form = await formRef.value.validate()

    const submitData = { ...form }

    // 如果是编辑，确保包含 medicineId
    if (dialogType.value === 'edit' && formData.value.medicineId) {
      submitData.medicineId = formData.value.medicineId
    }

    // 处理数值类型
    submitData.price = Number(submitData.price)
    submitData.salesVolume = Number(submitData.salesVolume)
    submitData.shelfLife = Number(submitData.shelfLife)
    submitData.commonCategoryId = Number(submitData.commonCategoryId)
    submitData.prescriptionCategoryId = Number(submitData.prescriptionCategoryId)

    const api = dialogType.value === 'add' ? addMedicine : updateMedicine
    const res = await api(submitData)

    if (res.code === 200) {
      ElMessage.success(dialogType.value === 'add' ? '添加成功' : '更新成功')
      dialogVisible.value = false
      fetchList()
    } else {
      ElMessage.error(res.msg || (dialogType.value === 'add' ? '添加失败' : '更新失败'))
    }
  } catch (error) {
    console.error('提交表单失败:', error)
    if (typeof error === 'string') {
      ElMessage.error(error)
    } else if (error.message) {
      ElMessage.error(error.message)
    } else {
      ElMessage.error('表单验证失败，请检查必填项')
    }
  } finally {
    submitLoading.value = false
  }
}

// 查看详情
const handleDetail = async (row) => {
  try {
    const res = await getMedicineDetail(row.medicineId)
    if (res.code === 200) {
      detailData.value = res.data
      drawerVisible.value = true
    } else {
      ElMessage.error(res.message || '获取详情失败')
    }
  } catch (error) {
    console.error('获取详情失败:', error)
    ElMessage.error('系统错误')
  }
}

// 删除药品
const handleDelete = async (row) => {
  try {
    const res = await deleteMedicine({ medicineId: row.medicineId })
    if (res.code === 200) {
      ElMessage.success('删除成功')
      fetchList()
    } else {
      ElMessage.error(res.message || '删除失败')
    }
  } catch (error) {
    console.error('删除失败:', error)
    ElMessage.error('系统错误')
  }
}

// 文件上传相关方法
const beforeUpload = (file) => {
  const isExcel = /\.(xlsx|xls)$/.test(file.name.toLowerCase())
  const isLt10M = file.size / 1024 / 1024 < 10

  if (!isExcel) {
    ElMessage.error('只能上传 Excel 文件!')
    return false
  }
  if (!isLt10M) {
    ElMessage.error('文件大小不能超过 10MB!')
    return false
  }
  return true
}

const handleFileChange = (file) => {
  if (file) {
    importFile.value = file.raw
  }
}

const handleFileRemove = () => {
  importFile.value = null
}

// 导入相关方法
const handleImport = () => {
  importDialogVisible.value = true
}

const closeImportDialog = () => {
  importDialogVisible.value = false
  importFile.value = null
  importResult.show = false
  if (uploadRef.value) {
    uploadRef.value.clearFiles()
  }
}

const submitImport = async () => {
  if (!importFile.value) {
    ElMessage.warning('请选择要导入的文件')
    return
  }

  let loading = null
  try {
    importLoading.value = true
    loading = ElLoading.service({
      text: '正在导入数据...',
      background: 'rgba(0, 0, 0, 0.7)'
    })

    const formData = new FormData()
    formData.append('file', importFile.value)

    const res = await importMedicine(formData)
    console.log('导入响应:', res)

    // 显示导入结果
    importResult.show = true
    if (res.code === 200 || res.code === 201) { // 处理成功和部分成功的情况
      importResult.successCount = res.data?.successCount || 0
      importResult.failCount = res.data?.failCount || 0
      importResult.errorMessages = res.data?.errorMessages || []

      if (res.code === 200) {
        ElMessage.success(res.msg || '导入成功')
        if (importResult.successCount > 0 && importResult.failCount === 0) {
          setTimeout(() => {
            closeImportDialog()
          }, 1500)
        }
      } else {
        ElMessage.warning(res.msg || '部分数据导入失败')
      }
      fetchList() // 刷新列表
    } else {
      importResult.successCount = 0
      importResult.failCount = 0
      importResult.errorMessages = [res.msg || '导入失败']
      ElMessage.error(res.msg || '导入失败')
    }
  } catch (error) {
    console.error('导入失败:', error)
    ElMessage.error('导入失败：' + (error.message || '未知错误'))
  } finally {
    importLoading.value = false
    if (loading) {
      loading.close()
    }
  }
}

// 导出方法
const handleExport = async () => {
  let loading = null
  try {
    if (total.value === 0) {
      ElMessage.warning('当前没有可导出的数据')
      return
    }

    loading = ElLoading.service({
      text: '正在导出数据...',
      background: 'rgba(0, 0, 0, 0.7)'
    })

    const exportParams = {
      medicineName: searchForm.medicineName || undefined,
      manufacturer: searchForm.manufacturer || undefined,
      commonCategoryId: searchForm.commonCategoryId || undefined
    }

    // 使用 blob 方式下载
    const res = await exportMedicine(exportParams, { responseType: 'blob' })

    if (res.type === 'application/json') {
      // 如果返回的是 JSON，说明可能有错误
      const reader = new FileReader()
      reader.onload = () => {
        const error = JSON.parse(reader.result)
        throw new Error(error.msg || '导出失败')
      }
      reader.readAsText(res)
      return
    }

    // 处理文件下载
    const blob = new Blob([res], {
      type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    })

    if (blob.size === 0) {
      throw new Error('导出的文件为空')
    }

    const fileName = '药品信息.xlsx'
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.style.display = 'none'
    link.href = url
    link.download = fileName
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    window.URL.revokeObjectURL(url)

    ElMessage.success('导出成功')
  } catch (error) {
    console.error('导出失败:', error)
    ElMessage.error('导出失败：' + (error.message || '未知错误'))
  } finally {
    if (loading) {
      loading.close()
    }
  }
}

// 下载模板方法
const downloadTemplate = async () => {
  let loading = null
  try {
    loading = ElLoading.service({
      text: '正在下载模板...',
      background: 'rgba(0, 0, 0, 0.7)'
    })

    // 使用 blob 方式下载
    const res = await downloadMedicineTemplate({ responseType: 'blob' })

    if (res.type === 'application/json') {
      // 如果返回的是 JSON，说明可能有错误
      const reader = new FileReader()
      reader.onload = () => {
        const error = JSON.parse(reader.result)
        throw new Error(error.msg || '下载失败')
      }
      reader.readAsText(res)
      return
    }

    const blob = new Blob([res], {
      type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    })

    if (blob.size === 0) {
      throw new Error('下载的模板文件为空')
    }

    const fileName = '药品导入模板.xlsx'
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.style.display = 'none'
    link.href = url
    link.download = fileName
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    window.URL.revokeObjectURL(url)

    ElMessage.success('模板下载成功')
  } catch (error) {
    console.error('下载模板失败:', error)
    ElMessage.error('下载模板失败：' + (error.message || '未知错误'))
  } finally {
    if (loading) {
      loading.close()
    }
  }
}

// 处理分页
const handleSizeChange = (val) => {
  queryParams.pageSize = val
  fetchList()
}

const handleCurrentChange = (val) => {
  queryParams.pageNum = val
  fetchList()
}

// 初始化
onMounted(async () => {
  await fetchCategories()
  fetchList()
})
</script>

<style lang="scss" scoped>
.medicine-container {
  padding: 20px;
  background-color: #f0f2f5;
  min-height: calc(100vh - 84px);

  .operation-area {
    margin-bottom: 16px;
    display: flex;
    justify-content: space-between;
    align-items: center;

    .left {
      .el-button {
        margin-right: 12px;
      }
    }

    .right {
      .el-input {
        width: 300px;
      }
    }
  }

  .search-area {
    margin-bottom: 16px;

    .search-form {
      display: flex;
      flex-wrap: wrap;
      gap: 12px;

      .el-form-item {
        margin-bottom: 0;
        margin-right: 0;
      }

      .category-select {
        width: 200px;
      }

      .search-buttons {
        margin-left: auto;
      }
    }
  }

  .table-area {
    background-color: #fff;
    box-shadow: 0 1px 4px rgba(0, 21, 41, .08);

    .el-table {
      border-radius: 4px;
      overflow: hidden;
    }
  }

  .medicine-info {
    display: flex;
    align-items: center;
    gap: 12px;

    .medicine-image {
      width: 50px;
      height: 50px;
      border-radius: 4px;
      object-fit: cover;
      box-shadow: 0 2px 4px rgba(0, 0, 0, .1);
      transition: transform .3s;

      &:hover {
        transform: scale(1.05);
      }
    }

    .no-image {
      width: 50px;
      height: 50px;
      border-radius: 4px;
      background-color: #f5f7fa;
      display: flex;
      align-items: center;
      justify-content: center;
      color: #909399;
      font-size: 24px;
    }

    .medicine-text {
      .medicine-name {
        font-weight: bold;
        margin-bottom: 4px;
        color: #303133;
      }

      .medicine-spec {
        color: #909399;
        font-size: 12px;
      }
    }
  }

  .category-info {
    display: flex;
    gap: 8px;
    justify-content: center;

    .el-tag {
      min-width: 80px;
      border-radius: 12px;
      padding: 0 12px;

      &.el-tag--plain {
        opacity: 0.6;
      }
    }
  }

  .price {
    color: #f56c6c;
    font-weight: bold;
    font-size: 14px;
  }
}

.pagination-container {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
  padding: 10px 0;
}

.upload-demo {
  text-align: center;
}

.el-upload__tip {
  padding: 8px 12px;
  background-color: #f5f7fa;
  border-radius: 4px;
  margin-top: 10px;
}

.tip-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

.tip-rules {
  font-size: 12px;
  color: #606266;
}

.tip-rules p {
  margin: 5px 0;
  font-weight: bold;
}

.tip-rules ol {
  margin: 5px 0;
  padding-left: 20px;
}

.tip-rules li {
  margin: 3px 0;
}

.import-result {
  margin-top: 20px;
  padding: 15px;
  background-color: #f5f7fa;
  border-radius: 4px;
}

.result-title {
  font-weight: bold;
  margin-bottom: 10px;
}

.result-content {
  font-size: 14px;
}

.success {
  color: #67c23a;
  font-weight: bold;
}

.error {
  color: #f56c6c;
  font-weight: bold;
}

.error-messages {
  margin-top: 10px;
}

.error-item {
  color: #f56c6c;
  margin: 5px 0;
  font-size: 12px;
}

:deep(.el-card__body) {
  padding: 16px;
}

:deep(.el-upload-dragger) {
  width: 100%;
}

:deep(.el-dialog__body) {
  padding-top: 20px;
}
</style>
